home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / net / mac / atalk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  19.5 KB  |  877 lines

  1. #include "atalk.hpp"
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #ifdef __POWERPC__
  6. DDPSocketListenerUPP DDPListener;
  7. UniversalProcPtr InitDDPListener;
  8. #else
  9. #include "ddplisten.hpp"
  10. #endif
  11.  
  12. #define ATALK_DEBUG
  13. #define PACKET_TYPE 0xca
  14.  
  15. //atalk_protocol atalk;
  16.  
  17. short    mppRef;
  18. short    adspRef;
  19.  
  20. /*
  21. FILE *log_file=NULL;
  22. extern int net_start();
  23. void net_log(char *st, void *buf, long size)
  24. {
  25.     
  26.   if (!log_file) 
  27.   {
  28.     if (net_start())
  29.       log_file=fopen("client.log","wb");
  30.     else
  31.       log_file=fopen("server.log","wb");
  32.   }
  33.  
  34.  
  35.     fprintf(log_file,"%s%d - ",st,size);
  36.     int i;
  37.     for (i=0;i<size;i++) 
  38.       if (isprint(*((unsigned char *)buf+i)))
  39.         fprintf(log_file,"%c",*((unsigned char *)buf+i));
  40.       else fprintf(log_file,"~");
  41.  
  42.     fprintf(log_file," : ");
  43.  
  44.     for (i=0;i<size;i++) 
  45.     fprintf(log_file,"%02x, ",*((unsigned char *)buf+i),*((unsigned char *)buf+i));
  46.     fprintf(log_file,"\n");
  47.     fflush(log_file);
  48.  
  49. } */
  50.  
  51. //////////////////////////////////////////////////////////////////////
  52. //
  53. //  AppleTalk base socket Methods
  54. //
  55.  
  56. atalk_base::atalk_base(int fd) : num(fd), select_flags(0)
  57. {
  58. }
  59.  
  60. atalk_base::~atalk_base()
  61. {
  62.     atalk.free_socket(num);
  63. }
  64.  
  65. //////////////////////////////////////////////////////////////////////
  66. //
  67. //  ADSP Socket Methods
  68. //
  69.  
  70. adsp_socket::adsp_socket(int fd) : atalk_base(fd)
  71. {
  72.     dsp.ioCRefNum = adspRef;
  73.     dsp.csCode = dspInit;
  74.     dsp.u.initParams.ccbPtr = (TPCCB)&ccb;
  75.  
  76.     // don't handle exceptions for now
  77.     dsp.u.initParams.userRoutine = 0;
  78.     // myDSPPBPtr->u.initParams.userRoutine = &myConnectionEvtUserRoutine;
  79.  
  80.     dsp.u.initParams.sendQSize = QSIZE;                    // size of send queue
  81.     dsp.u.initParams.sendQueue = &send_queue;        // send-queue buffer
  82.     dsp.u.initParams.recvQSize = QSIZE;                    // size of receive queue
  83.     dsp.u.initParams.recvQueue = &recv_queue;        // receive-queue buffer
  84.     dsp.u.initParams.attnPtr = &attn_buff;            // receive-attention buffer
  85.     dsp.u.initParams.localSocket = 0;                        // let ADSP assign socket
  86. //    gDspCCB.myA5 = SetCurrentA5();                                            // save A5 for the user routine
  87.  
  88.     // establish a connection end
  89.  
  90.     if (PBControl((ParmBlkPtr) &dsp, FALSE))
  91.         dprintf("ATALK ADSP Initialization Error\n");
  92.  
  93.     conn = dsp.ccbRefNum;    // save CCB ref num for later
  94. }
  95.  
  96. int adsp_socket::open(atalk_address *addr)
  97. {
  98.     OSErr err;
  99.     
  100.     dsp.ioCRefNum = adspRef;    // ADSP driver ref num
  101.     dsp.csCode = dspOpen;
  102.     dsp.ccbRefNum = conn;            // connection ref num
  103.     dsp.u.openParams.remoteAddress = addr->addr;    
  104.     dsp.u.openParams.filterAddress.aNet = addr->addr.aNet;
  105.     dsp.u.openParams.filterAddress.aNode = addr->addr.aNode;
  106.     dsp.u.openParams.filterAddress.aSocket = 0;
  107.     dsp.u.openParams.ocMode = ocRequest;     // open connection mode
  108.     dsp.u.openParams.ocInterval = 6;             // retry every second
  109.     dsp.u.openParams.ocMaximum = 255;            // don't quit trying
  110.  
  111.     // open a connection
  112.     if (err = PBControl((ParmBlkPtr)&dsp, FALSE))
  113.     {
  114.         dprintf("ATALK ADSP dspOpen error %d\n",err);
  115.         return err;
  116.     }
  117.     return 0;
  118. }
  119.  
  120. void adsp_socket::cleanup() 
  121. {
  122.     dsp.ioCRefNum = adspRef;            // ADSP driver ref num
  123.     dsp.csCode = dspRemove;
  124.     dsp.ccbRefNum = conn;                    // connection ref num
  125.     dsp.u.closeParams.abort = 0;    // don't close until everything is sent and received
  126.  
  127.     if (PBControl((ParmBlkPtr) &dsp, FALSE))
  128.         dprintf("ATALK ADSP remove error");
  129. }
  130.  
  131. int adsp_socket::ready_to_read() 
  132. {
  133.     dsp.csCode = dspStatus;
  134.     PBControl((ParmBlkPtr)&dsp, 0);
  135.     return (dsp.u.statusParams.recvQPending != 0 || error());
  136. }
  137.  
  138. int adsp_socket::error() 
  139. {
  140.     return ( ccb.userFlags>=4 );
  141. }
  142.  
  143. int adsp_socket::ready_to_write() 
  144. {
  145.     dsp.ioCRefNum = adspRef;                // ADSP driver ref num
  146.     dsp.csCode = dspStatus;
  147.     dsp.ioCompletion = 0;
  148.     dsp.ccbRefNum = conn;
  149.     PBControl((ParmBlkPtr)&dsp, 0);
  150.     return (dsp.u.statusParams.sendQPending == 0 || error());
  151. }
  152.  
  153. int adsp_socket::read(void *buf, int size, net_address **addr) 
  154. {
  155.   if (addr) 
  156.       *addr=NULL;
  157.  
  158.     do
  159.     {
  160.         if (error())
  161.             return 0;
  162.             
  163.         dsp.ioCRefNum = adspRef;                // ADSP driver ref num
  164.         dsp.csCode = dspStatus;
  165.         dsp.ioCompletion = 0;
  166.         dsp.ccbRefNum = conn;
  167.         PBControl((ParmBlkPtr)&dsp, 0);
  168.     } while (dsp.u.statusParams.recvQPending < size);
  169.  
  170.     int fu = dsp.u.statusParams.recvQPending;
  171.  
  172.     dsp.ioCRefNum = adspRef;                // ADSP driver ref num
  173.     dsp.csCode = dspRead;
  174.     dsp.ccbRefNum = conn;                        // connection ref num
  175.     dsp.u.ioParams.reqCount = size;     // read this number of bytes
  176.     dsp.u.ioParams.dataPtr = (Ptr)buf;    // pointer to read buffer
  177.  
  178.     // perform read
  179.     if (PBControl( (ParmBlkPtr)&dsp, FALSE))
  180.     {
  181.         dprintf("ATALK ADSP read error\n");
  182.         return 0;
  183.     }
  184.  
  185. //    dprintf("ATALK DSP read %d of %d, wanted %d\n", 
  186. //        dsp.u.ioParams.actCount,
  187. //        fu,
  188. //        size);
  189.  
  190.   return dsp.u.ioParams.actCount;
  191. }
  192.  
  193. int adsp_socket::write(void *buf, int size, net_address *addr)
  194.   if (addr)
  195.       dprintf("Cannot change address for this socket type\n");
  196.  
  197.     while (!ready_to_write()) 
  198.         if (error())
  199.             return 0;
  200.  
  201.     dsp.ioCRefNum = adspRef;           // ADSP driver ref num
  202.     dsp.csCode = dspWrite;
  203.     dsp.ccbRefNum = conn;              // connection ref num
  204.     dsp.u.ioParams.reqCount = size;  // write this numberof bytes
  205.     dsp.u.ioParams.dataPtr = buf;      // pointer to send queue
  206.     dsp.u.ioParams.eom = 0;             // 1 means last byte is logical end-of-message
  207.     dsp.u.ioParams.flush = 1;           // 1 means send data now
  208.  
  209.     // perform write
  210.     if (PBControl( (ParmBlkPtr)&dsp, FALSE))
  211.     {
  212.         dprintf("ATALK ADSP Write error\n");
  213.         return 0;
  214.     }
  215.  
  216.     int ret = dsp.u.ioParams.actCount;
  217.  
  218.     while (!ready_to_write()) 
  219.         if (error())
  220.             return 0;
  221.  
  222. //    dprintf("ATALK DSP wrote %d of %d\n",ret,size);
  223.  
  224.   return ret; 
  225. }
  226.  
  227. //////////////////////////////////////////////////////////////////////
  228. //
  229. //  ADSP Listener Socket Methods
  230. //
  231.  
  232. adsp_listener::adsp_listener(int fd) : atalk_base(fd)
  233. {
  234.     // initialize listener with socket
  235.     dsp.ioCRefNum = adspRef;
  236.     dsp.csCode = dspCLInit;
  237.     dsp.u.initParams.ccbPtr = (TPCCB)&ccb;
  238.     dsp.u.initParams.localSocket = 0;  // get new "port"
  239. //    gDspCCB.myA5 = SetCurrentA5();                                            // save A5 for the user routine
  240.  
  241.     if (PBControl((ParmBlkPtr) &dsp, FALSE))
  242.         dprintf("ATALK Listener Initialization Error\n");
  243.  
  244.     conn = dsp.ccbRefNum;    // save CCB ref num for later
  245. }
  246.  
  247. int adsp_listener::listen(int port)
  248. {
  249.     // perform listen
  250.     dsp.ioCRefNum = adspRef;
  251.     dsp.csCode = dspCLListen;
  252.     dsp.ccbRefNum = conn;
  253.     dsp.ioResult = 1;
  254.     
  255.     // don't filter any addresses
  256.     dsp.u.openParams.filterAddress.aNet = 0;
  257.     dsp.u.openParams.filterAddress.aNode = 0;
  258.     dsp.u.openParams.filterAddress.aSocket = 0;
  259. //    gDspCCB.myA5 = SetCurrentA5();                                            // save A5 for the user routine
  260.  
  261.     if (PBControl((ParmBlkPtr) &dsp, TRUE))
  262.     {
  263.         dprintf("ATALK Listener Error\n");
  264.         return 0;
  265.     }
  266.     listening = 1;
  267.     return 1;
  268. }
  269.  
  270. void adsp_listener::cleanup() 
  271. {
  272.     dsp.csCode = dspCLRemove;
  273.     dsp.ioCompletion = 0;
  274.     dsp.ioCRefNum = adspRef;            // ADSP driver ref num
  275.     dsp.ccbRefNum = conn;                    // connection ref num
  276.     dsp.u.closeParams.abort = 1;    // close outstanding requests
  277.  
  278.     if (PBControl((ParmBlkPtr) &dsp, FALSE))
  279.         dprintf("ATALK ADSP Listener remove error");
  280. }
  281.  
  282. int adsp_listener::ready_to_read()
  283. {
  284.     return dsp.ioResult != 1;
  285. }
  286.  
  287. net_socket *adsp_listener::accept(net_address *&addr)
  288. {
  289.     if (!ready_to_read())
  290.     {
  291.         dprintf("Listener not ready!\n");
  292.         return 0;
  293.     }
  294.     int fd = atalk.new_socket();
  295.     
  296.     adsp_socket *sock = new adsp_socket(fd);
  297.     atalk.socket[fd] = sock;
  298.     
  299.     addr = new atalk_address(&dsp.u.openParams.remoteAddress);
  300.     
  301.     sock->dsp.ioCRefNum = adspRef;
  302.     sock->dsp.csCode = dspOpen;
  303.     sock->dsp.ccbRefNum  = sock->conn;
  304.     sock->dsp.u.openParams.ocMode = ocAccept;
  305.     sock->dsp.u.openParams.ocInterval = 6;
  306.     sock->dsp.u.openParams.ocMaximum = 3;
  307.     sock->dsp.u.openParams.remoteCID = dsp.u.openParams.remoteCID;
  308.     sock->dsp.u.openParams.remoteAddress = dsp.u.openParams.remoteAddress;
  309.     sock->dsp.u.openParams.sendSeq = dsp.u.openParams.sendSeq;
  310.     sock->dsp.u.openParams.attnSendSeq = dsp.u.openParams.attnSendSeq;
  311.     sock->dsp.u.openParams.sendWindow = dsp.u.openParams.sendWindow;
  312.  
  313.     if (PBControl((ParmBlkPtr) &sock->dsp, 0))
  314.         dprintf("ATALK Accept Error\n");
  315.  
  316.     dsp.ioResult = 1;
  317.     listen(0);
  318.     
  319.     return sock;
  320. }
  321.  
  322. //////////////////////////////////////////////////////////////////////
  323. //
  324. //  DDP Socket Methods
  325. //
  326.  
  327. ddp_socket::ddp_socket(int fd) : atalk_base(fd)
  328. {
  329.     dprintf("DDP new\n");
  330.     ddp.abResult = 1;
  331.     ddp.ddpActCount = 0;
  332.     ddp.ddpReqCount = 586;
  333.     ddp.ddpDataPtr = buffer;
  334.  
  335.     struct sDDPBuff *db = (struct sDDPBuff *)(&buffer[602]);
  336.  
  337.     db->Start = (struct sPacket *)(&db->Data);
  338.     db->End = (struct sPacket *)((char*)db->Start + 602*16);
  339.     db->Tail = db->Head = db->Start;
  340.     db->Count = 0;
  341.  
  342.     // note!!!! can only do once!
  343.     CallUniversalProc(InitDDPListener,
  344.         kRegisterBased
  345.              | REGISTER_ROUTINE_PARAMETER(1, kRegisterA1, SIZE_CODE(sizeof(long))),
  346.         (char*)db);
  347.  
  348.     atalk.mpp.MPPioRefNum = mppRef;
  349.     atalk.mpp.MPPioCompletion = 0L;
  350.     atalk.mpp.DDPsocket = 0;
  351.     atalk.mpp.DDPlistener = DDPListener;
  352.     
  353.     if (POpenSkt(&atalk.mpp,FALSE))
  354.         dprintf("ATALK DDP Open Socket Error\n");
  355.         
  356.     socket = atalk.mpp.DDPsocket;
  357.     
  358.     dprintf("allocated DDP at socket %d\n",socket);
  359.     
  360.     def_addr.aNet = 0;
  361.     def_addr.aNode = 0;
  362.     def_addr.aSocket = 0;
  363. }
  364.  
  365. void ddp_socket::cleanup()
  366. {
  367.     atalk.mpp.MPPioRefNum = mppRef;
  368.     atalk.mpp.DDPsocket = socket;
  369.     
  370.     if (PCloseSkt(&atalk.mpp,FALSE))
  371.         dprintf("Error closing socket");
  372. }
  373.  
  374. int ddp_socket::ready_to_read()
  375. {
  376.     return ( ((struct sDDPBuff *)(&buffer[602]))->Count > 0);
  377. }
  378.  
  379. int ddp_socket::error()
  380. {
  381.     return 0;
  382. }
  383.  
  384. //extern void do_flip(int num);
  385.  
  386. int ddp_socket::read(void *buf, int size, net_address **addr)
  387. {
  388.     int cnt = size;
  389.     
  390.     while (!ready_to_read()) ;
  391.     
  392. //    do_flip(0);
  393.     
  394.     struct sDDPBuff *db = (struct sDDPBuff *)(&buffer[602]);
  395.     struct sPacket *pk = db->Tail;
  396.  
  397.     cnt = (pk->Count<cnt)? pk->Count : cnt;
  398.     db->Count--;
  399.     memcpy(buf,&pk->Data,cnt);
  400.  
  401. //        dprintf("DDP Got %d of %d from %d:%d:%d\n",cnt,size,
  402. //            ddp.ddpAddress.aNet,ddp.ddpAddress.aNode,ddp.ddpAddress.aSocket);
  403.         
  404.     if (addr)
  405.         *addr = new atalk_address(&pk->Addr);
  406.  
  407.     pk = (struct sPacket *)((char *)pk + 602);
  408.     if (pk>=db->End)
  409.         pk = db->Start;
  410.     db->Tail = pk;
  411.  
  412.     return cnt;
  413. }
  414.  
  415. int ddp_socket::write(void *buf, int size, net_address *address)
  416. {
  417.     char wds[14];
  418.     char header[20];
  419.     AddrBlock *addr;
  420.  
  421.     if (address)
  422.         addr = &((atalk_address*)address)->addr;
  423.     else
  424.         addr = &def_addr;
  425.         
  426.     BuildDDPwds((Ptr)wds, (Ptr)header, (Ptr)buf, *addr, PACKET_TYPE, size);
  427.  
  428.     atalk.mpp.DDP.ioCompletion = nil;
  429.     atalk.mpp.DDP.socket = socket;
  430.     atalk.mpp.DDP.checksumFlag = 0;
  431.     atalk.mpp.DDP.u.wdsPointer = (Ptr) &wds;
  432.  
  433.     if (PWriteDDP(&atalk.mpp, FALSE))
  434.         dprintf("ATALK ADD Write error\n");
  435.  
  436. //    dprintf("DDP Wrote %d to %d:%d:%d\n",size,
  437. //        addr->aNet, addr->aNode, addr->aSocket);
  438.  
  439.     return 0;
  440. }
  441.  
  442. //////////////////////////////////////////////////////////////////////
  443. //
  444. //  ATALK Protocol Methods
  445. //
  446.  
  447. net_address *atalk_protocol::get_local_address()
  448. {
  449.     short node,net;
  450.     
  451.     GetNodeAddress(&node,&net);
  452.   atalk_address *a=new atalk_address(net,node);
  453.  
  454.     return a;
  455. }
  456.  
  457. net_address *atalk_protocol::get_node_address(char *&server_name, int def_port, int force_port)
  458. {
  459.     // not really used now
  460.  
  461.     return 0;
  462. }
  463.  
  464. net_socket *atalk_protocol::connect_to_server(net_address *addr, net_socket::socket_type sock_type)
  465. {
  466.   if (addr->protocol_type()!=net_address::ATALK)
  467.   {
  468.     fprintf(stderr,"Procotol type not supported in the executable\n");
  469.     return NULL;
  470.   }
  471.  
  472. #ifdef ATALK_DEBUG
  473.     char s[256];
  474.     atalk_address *tmp = (atalk_address *)get_local_address();
  475.     tmp->store_string(s,256);
  476.     dprintf("[%s] trying to connect\n",s);
  477.  
  478.     delete tmp;
  479. #endif
  480.  
  481.     int fd = new_socket();
  482.  
  483.   if (sock_type==net_socket::SOCKET_SECURE)
  484.   {
  485.       adsp_socket *s;
  486.     socket[fd] = s = new adsp_socket(fd);
  487.     s->open((atalk_address *)addr);
  488.     return socket[fd];
  489.   }
  490.   else
  491.   {
  492.       ddp_socket *d;
  493.     socket[fd] = d = new ddp_socket(fd);
  494.     d->def_addr = ((atalk_address*)addr)->addr;
  495.     return socket[fd];
  496.   }
  497. }
  498.  
  499. net_socket *atalk_protocol::create_listen_socket(int &port, net_socket::socket_type sock_type)
  500. {
  501.     int fd = new_socket();
  502.  
  503.     if (fd<0)
  504.         return 0;
  505.         
  506.     if (sock_type == net_socket::SOCKET_SECURE)
  507.     {
  508.         adsp_listener *l;
  509.  
  510.         socket[fd] = l = new adsp_listener(fd);
  511.  
  512.         listener = l->dsp.u.initParams.localSocket;
  513.         port = listener;
  514.     
  515.       if (l->listen(port)==0)
  516.       {   
  517.         delete l;
  518.         return 0;
  519.       }
  520.     }
  521.     else
  522.     {
  523.         ddp_socket *d;
  524.         
  525.         socket[fd] = d = new ddp_socket(fd);
  526.         port = d->get_socket();
  527.  
  528.         // get rid of this when real.  used only by test program
  529. //        listener = port;
  530.     }
  531.  
  532.     return socket[fd];
  533. }
  534.  
  535. atalk_protocol::atalk_protocol()
  536. : ok(0), net_protocol(), registered(0), listener(0), querying(0)
  537. {
  538.     if (OpenDriver("\p.MPP", &mppRef))
  539.         return;
  540.  
  541.     if (OpenDriver("\p.DSP", &adspRef))
  542.         return;
  543.  
  544.     for (int i=0; i<MAXSOCKS; i++)
  545.         socket[i] = 0;
  546.     for (int i=0; i<MAXSOCKS-1; i++)
  547.         usage[i] = i+1;
  548.     usage[MAXSOCKS-1] = -1;
  549.     free = 0;
  550.  
  551.     Handle listener;
  552.  
  553.     listener = GetResource('SOCK',0);
  554.  
  555.     if (!listener)
  556.         return;
  557.  
  558.     HLock(listener);
  559.     InitDDPListener = (UniversalProcPtr)NewRoutineDescriptor((ProcPtr)(*listener+0x12),
  560.         kRegisterBased
  561.          | REGISTER_ROUTINE_PARAMETER(1, kRegisterA1, SIZE_CODE(sizeof(long))),kM68kISA);
  562.     DDPListener = (UniversalProcPtr) (*listener+0x14);
  563.  
  564.     // zone info initialization
  565.     last_block = 0;
  566.     last_pos = 1024;
  567.     num_zones = 0;
  568.     MyZone[0] = 1;
  569.     MyZone[1] = '*';
  570.  
  571.     ok = 1;
  572. }
  573.  
  574. int atalk_protocol::new_socket()
  575. {
  576.     int ret = free;
  577.     
  578.     if (ret >=0)
  579.     {
  580.         free = usage[free];
  581.         usage[ret] = -2;
  582.     }
  583.     else
  584.     {
  585.         dprintf("Out of atalk_protocol sockets");
  586.         exit(0);
  587.     }
  588.  
  589.     dprintf("ATALK created fd = %d\n",ret);
  590.  
  591.     return ret;
  592. }
  593.  
  594. void atalk_protocol::free_socket(int num)
  595. {
  596.     if (usage[num] != -2)
  597.     {
  598.         dprintf("Freed bad atalk_socket %d\n",num);
  599. //        exit(0);
  600.     }
  601.     usage[num] = free;
  602.     free = num;
  603.     socket[num] = 0;
  604.  
  605.     dprintf("ATALK freed fd = %d\n",num);
  606. }
  607.  
  608. void atalk_protocol::cleanup()
  609. {
  610.     if (registered)
  611.         end_notify();
  612.     registered = 0;    
  613.     
  614.     for (int i=0; i<MAXSOCKS; i++)
  615.         if (socket[i])
  616.         {
  617.             delete socket[i];
  618.             free_socket(i);
  619.         }
  620. }
  621.  
  622. int atalk_protocol::select(int block)
  623. {
  624.     int i,count=0;
  625.  
  626.     for (i=0; i<MAXSOCKS; i++)
  627.         if (socket[i])
  628.             count += socket[i]->select_count();
  629.  
  630.     return count;
  631. }
  632.  
  633. net_socket *atalk_protocol::start_notify(int port, void *data, int len)
  634. {
  635.     if (registered)
  636.         return 0;
  637.         
  638.     // set up NBP names table entry
  639.     Name[0] = len;
  640.     memcpy(&Name[1],data,len);
  641.     NBPSetNTE((Ptr) &NTEName, Name, "\pAbuseServer", "\p*", listener);
  642.  
  643.     // set up PRegisterName parameters
  644.     mpp.MPPioCompletion = 0L;
  645.     mpp.MPPioRefNum = mppRef;
  646.     mpp.NBP.interval = 7;                                                // retransmit every 7*8=56 ticks
  647.     mpp.NBP.count = 3;                                                    // and retry 3 times
  648.     mpp.NBP.nbpPtrs.entityPtr = (Ptr) &NTEName;    // name to register
  649.     mpp.NBP.parm.verifyFlag = 1;                                // verify this name
  650.  
  651. #ifdef ATALK_DEBUG
  652.     char s[256];
  653.     atalk_address *tmp = (atalk_address *)get_local_address();
  654.     tmp->set_port(listener);
  655.     tmp->store_string(s,256);
  656.     dprintf("registering [%s] as %s\n",s,(char*)data);
  657.     
  658.     delete tmp;
  659. #endif
  660.  
  661.     if (PRegisterName(&mpp, FALSE))
  662.         dprintf("ATALK Couldn't Register name\n");
  663.  
  664.     registered = 1;
  665.  
  666.     return 0;
  667. }
  668.  
  669. void atalk_protocol::end_notify()
  670. {
  671.     EntityName    entity;
  672.  
  673.     NBPSetEntity((Ptr) &entity, Name, "\pAbuseServer", "\p*");
  674.     mpp.MPPioCompletion = 0L;
  675.     mpp.MPPioRefNum = mppRef;
  676.     mpp.NBP.nbpPtrs.entityPtr = (Ptr)&entity;
  677.     if (PRemoveName(&mpp,FALSE))
  678.         dprintf("ATALK Unregister name error\n");
  679. }
  680.  
  681. net_address *atalk_protocol::find_address(int port, char *name)
  682. // name should be a 256 byte buffer
  683. {
  684.     EntityName    entity;
  685.     atalk_address addr;
  686.  
  687.     if (!querying)
  688.     {
  689.         NBPSetEntity((Ptr) &entity, "\p=", "\pAbuseServer", MyZone);
  690.         
  691.         nbp.MPPioRefNum = mppRef;
  692.         nbp.MPPioCompletion = 0L;
  693.         nbp.NBPinterval = 7;// retransmit every 7*8=56 ticks
  694.         nbp.NBPcount = 3;    // and retry 3 times
  695.         nbp.NBPentityPtr = (Ptr) &entity;
  696.         nbp.NBPretBuffPtr = (Ptr) Buff;
  697.         nbp.NBPretBuffSize = sizeof(Buff);
  698.         nbp.NBPmaxToGet = 10;
  699.         nbp.MPPioResult = 1;
  700.         nbp.NBPnumGotten = 0;
  701.     
  702.         if (PLookupName(&nbp,TRUE))
  703.             dprintf("ATALK Name Lookup error\n");
  704.  
  705.         querying = 1;
  706.         
  707.         return 0;
  708.     }
  709.     else
  710.     {
  711.         if (nbp.MPPioResult == 1)
  712.             return 0;
  713.  
  714.         querying = 0;
  715.         
  716.         if (nbp.MPPioResult != 0)
  717.             return 0;
  718.         
  719.         for (int i=0; i<nbp.NBPnumGotten; i++)
  720.         {
  721.             int found = 0;
  722.             
  723.             NBPExtract((Ptr)Buff,nbp.NBPnumGotten,i+1,&entity,&addr.addr);
  724.     
  725.         for (p_request p = servers.begin(); !found && p!=servers.end(); ++p)
  726.             if ( *((*p)->addr) == addr )
  727.                 found = 1;
  728.         for (p_request q = returned.begin(); !found && q!=returned.end(); ++q)
  729.             if ( *((*q)->addr) == addr )
  730.                 found = 1;
  731.                 
  732.             if (!found) 
  733.             {
  734.                 RequestItem *r = new RequestItem;
  735.     
  736.                 for (int i=0; i<entity.objStr[0]; i++)
  737.                     r->name[i] = entity.objStr[1+i];
  738.                 r->name[entity.objStr[0]] = 0;
  739.     
  740.                 r->addr = new atalk_address(&addr.addr);
  741.           servers.insert(r);
  742. #ifdef ATALK_DEBUG
  743.                 char s[256];
  744.                 
  745.                 addr.store_string(s,256);
  746.                 dprintf("accepted %s\n",s);
  747. #endif
  748.             }
  749.         }
  750.     
  751.         if (servers.empty())
  752.             return 0;
  753.     
  754.       servers.move_next(servers.begin_prev(), returned.begin_prev());
  755.         atalk_address *ret = (atalk_address*)(*returned.begin())->addr->copy();
  756.         strcpy(name,(*returned.begin())->name);
  757.     
  758. #ifdef ATALK_DEBUG
  759.         char s[256];
  760.         
  761.         ret->store_string(s,256);
  762.         dprintf("Found [%s]\n",s);
  763. #endif
  764.  
  765.       return ret;
  766.     }
  767. }
  768.  
  769. void atalk_protocol::reset_find_list()
  770. {
  771.     p_request p;
  772.     
  773.     for (p=servers.begin(); p!=servers.end(); ++p)
  774.         delete (*p)->addr;
  775.     for (p=returned.begin(); p!=returned.end(); ++p)
  776.         delete (*p)->addr;
  777.         
  778.   servers.erase_all();
  779.   returned.erase_all();
  780. }
  781.  
  782. char ** atalk_protocol::GetZones(int &num)
  783. {
  784.     if (num_zones==0)
  785.     {
  786.         XPPParamBlock xppPB;
  787.         char buffer[578];
  788.         OSErr err = noErr;
  789.     
  790.         xppPB.XCALL.xppTimeout = 3;
  791.         xppPB.XCALL.xppRetry = 4;    
  792.         xppPB.XCALL.zipBuffPtr = buffer;    
  793.         xppPB.XCALL.zipLastFlag = 0;    
  794.         xppPB.XCALL.zipInfoField[1] = 0;    
  795.         xppPB.XCALL.zipInfoField[2] = 0;    
  796.         
  797.         while (xppPB.XCALL.zipLastFlag == 0 && err==noErr)
  798.         {
  799.             err = GetZoneList(&xppPB, FALSE);
  800.             if (err)
  801.                 dprintf("ATALK GetZoneList error %d\n",err);
  802.             else
  803.             {
  804.                 unsigned char *p = (unsigned char *)buffer;
  805.                 for (int i=0; i<xppPB.XCALL.zipNumZones; i++)
  806.                 {
  807.                     AddZone(p);
  808.                     p += (*p) + 1;
  809.                 } 
  810.             }
  811.         }
  812.     }
  813.     
  814.     num = num_zones;
  815.     return ZoneName;
  816. }
  817.  
  818. void atalk_protocol::SetZone(char *name)
  819. {
  820.     int l = strlen(name);
  821.     MyZone[0] = l;
  822.     memcpy(&MyZone[1],name,l);
  823. }
  824.  
  825. int atalk_protocol::GetMyZone(char *name)
  826. {
  827.     XPPParamBlock xppPB;
  828.     char buffer[33];
  829.     OSErr err = noErr;
  830.  
  831.     xppPB.XCALL.xppTimeout = 3;
  832.     xppPB.XCALL.xppRetry = 4;    
  833.     xppPB.XCALL.zipBuffPtr = buffer;    
  834.     xppPB.XCALL.zipLastFlag = 0;    
  835.     xppPB.XCALL.zipInfoField[1] = 0;    
  836.     xppPB.XCALL.zipInfoField[2] = 0;    
  837.         
  838.     if (::GetMyZone(&xppPB, FALSE) == noErr)
  839.     {
  840.         memcpy(name,(char*)&buffer[1],buffer[0]);
  841.         name[buffer[0]] = 0;
  842.         
  843.         return 0;
  844.     }
  845.     else
  846.         return -1;
  847. }
  848.  
  849. void atalk_protocol::AddZone(unsigned char *name)
  850. {
  851.     if (num_zones>=MAXZONENAMES)
  852.         return;
  853.  
  854.     if (name[0] + last_pos + 1> 1024)
  855.     {
  856.         zones.insert(last_block = new sZoneBlock);
  857.         last_pos = 0;
  858.     }
  859.     char *ret = &last_block->Name[last_pos];
  860.     last_pos += name[0] + 1;
  861.     
  862.     memcpy(ret,(char*)&name[1],name[0]);
  863.     ret[name[0]] = 0;
  864.     
  865.     ZoneName[num_zones++] = ret;
  866. }
  867.  
  868. void atalk_protocol::FreeZones()
  869. {
  870.     for (p_zoneblock p = zones.begin(); p != zones.end(); ++p)
  871.         delete (*p);
  872.         
  873.     zones.erase_all();
  874.     num_zones = 0;
  875. }
  876.